
#include "thread.h"

#include <QTimer>
#include <QTime>
#include <QDebug>
#include <qdatetime.h>

#include <iostream>
#include <fstream>

using namespace std;

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <getopt.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <malloc.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

#include <asm/types.h>
#include "global.h"


int feedout(size_t n){

    msync((framecontrol[0].start), 24*sizeof(int), MS_SYNC);
    framecontrol[0].STATED = (framecontrol[0].start)[17];

    if((framecontrol[0].STATED == 0)||(framecontrol[0].STATED == 1)){
        memcpy(readtemp[0].fbV,readtemp[1].fbV,n);
        return(0);
    }
    else{
        usleep(1000);
        return(1);
    }

}


unsigned int readtable()
{
    unsigned int table0[10][7]={0};
    unsigned int table[384] = {0};
    unsigned int * ptr;
    ptr = (unsigned int *)table;
    ifstream infile;
    infile.open("/home/linaro/tiny_yolo_table.txt");
    for(int i =0;i<10;i++)
    {
        for (int j =0;j<7;j++)
        {
            infile >> table0[i][j];
        }
    }
    infile.close();
    for(int i =0;i<10;i++)
    {
        for(int j=0;j<3;j++)
            {
                table[3*i+j]      =table0[i][j];
                table[128+3*i+j]  =table0[i][j+2];
                table[128+3*i]    =table0[i][0];
                table[2*128+3*i+j]=table0[i][j+4];
                table[2*128+3*i]  =table0[i][0];
            }
    }
    //qDebug() << "Loaded,transfer start...";
    //ui->label_3->setText("transfer start");
    //ui->label_3->show();

    memcpy(readtemp[1].fbV,ptr,384*sizeof(unsigned int));

    //msync(readtemp[1].fbV, 2*1024*1024*sizeof(char), MS_SYNC);
    while(feedout(384*sizeof(unsigned int))){;}

    framecontrol[0].STATED = 2;
    framecontrol[0].ATT = 1;
    framecontrol[0].NUMD = 384*sizeof(unsigned int);
    framecontrol[0].PIECEEND = 1;
    framecontrol[0].WP = 0;

    (framecontrol[0].start)[18] = framecontrol[0].ATT;
    (framecontrol[0].start)[19] = framecontrol[0].LAYER;
    (framecontrol[0].start)[20] = framecontrol[0].NUMD;
    (framecontrol[0].start)[21] = framecontrol[0].PIECEEND;
    (framecontrol[0].start)[22] = framecontrol[0].WP;

    (framecontrol[0].start)[17] = framecontrol[0].STATED;
    qDebug() << "transfer table complete...";

    return 0;
}




//传输1-27层（不含第六层的1，2，3层）的权重数据

unsigned int readwdata_2m(int i)
{
    unsigned int temp;
    QString data_name;
    std::string str;
    //data_name.sprintf("%s%d%s", "./weights_data/conv", i, "_h_weights_0.txt");
    data_name.sprintf("%s%d%s", "/home/linaro/weights3/conv", i, "_h_weights_0.txt");
    str = data_name.toStdString();
    const char* ch = str.c_str();
    ifstream file_name(ch);
    if (!file_name.is_open())
    {
        qDebug() << "open file error!";
        return 0;
    }
    int k = 0;
    while (!file_name.eof())
    {
        file_name>>hex>>temp;
        readtemp[1].fbV[k] = (unsigned char)temp;
        k = k + 1;
        if (k == 2*1024*1024)
        {
            //msync(readtemp[1].fbV, 2*1024*1024*sizeof(char), MS_SYNC);
            while(feedout(2*1024*1024*sizeof(char))){;}

            framecontrol[0].STATED = 2;
            framecontrol[0].ATT = 2;
            framecontrol[0].LAYER = i;
            framecontrol[0].NUMD = 2*1024*1024*sizeof(char);
            framecontrol[0].PIECEEND = 0;
            framecontrol[0].WP = 0;

            (framecontrol[0].start)[18] = framecontrol[0].ATT;
            (framecontrol[0].start)[19] = framecontrol[0].LAYER;
            (framecontrol[0].start)[20] = framecontrol[0].NUMD;
            (framecontrol[0].start)[21] = framecontrol[0].PIECEEND;
            (framecontrol[0].start)[22] = framecontrol[0].WP;

            (framecontrol[0].start)[17] = framecontrol[0].STATED;

            msync((framecontrol[0].start), 24*sizeof(int), MS_SYNC);

            k=0;
            qDebug() << "...";
        }
    }
    if(k >=0)
    {
        //msync(readtemp[1].fbV, 2*1024*1024*sizeof(char), MS_SYNC);
        while(feedout(k*sizeof(char))){;}
        framecontrol[0].STATED = 2;
        framecontrol[0].ATT = 2;
        framecontrol[0].LAYER = i;
        framecontrol[0].NUMD = k*sizeof(char);
        framecontrol[0].PIECEEND = 1;
        framecontrol[0].WP = 0;

        (framecontrol[0].start)[18] = framecontrol[0].ATT;
        (framecontrol[0].start)[19] = framecontrol[0].LAYER;
        (framecontrol[0].start)[20] = framecontrol[0].NUMD;
        (framecontrol[0].start)[21] = framecontrol[0].PIECEEND;
        (framecontrol[0].start)[22] = framecontrol[0].WP;

        (framecontrol[0].start)[17] = framecontrol[0].STATED;

        msync((framecontrol[0].start), 24*sizeof(int), MS_SYNC);

        qDebug() << "...!";
    }
    file_name.close();
    //printf("conv_%d_h_weights_0.txt has been sent!\n",i);
    //QString s;
    //s.sprintf("conv_%d_h_weights_0.txt has been sent!\n",i);
    //qDebug()<<s;
    //ui->label_3->setText(s);
    //ui->label_3->show();
    return(0);
}





unsigned int readbdata_2m(int i)
{
    unsigned int temp;
    QString data_name;
    std::string str;
    //data_name.sprintf("%s%d%s", "./hardware_bias2/conv", i, "_h_biases_0.txt");
    data_name.sprintf("%s%d%s", "/home/linaro/bias3/conv", i, "_h_biases_0.txt");
    str = data_name.toStdString();
    const char* ch = str.c_str();
    ifstream file_name(ch);
    if (!file_name.is_open())
    {
        qDebug() << "open file error!";
        return 0;
    }
    int k = 0;

    //unsigned int* fbv32;
    //fbv32 = (unsigned int*)(readtemp[1].fbV);

    while (!file_name.eof())
    {
        file_name>>hex>>temp;


        //fbv32[k] = temp;
        readtemp[1].fbV[k] = (unsigned char)temp;

        k = k + 1;
        if (k == 2*1024*1024)
        //if (k == 2*1024*1024/4)
        {
            //msync(readtemp[1].fbV, 2*1024*1024*sizeof(char), MS_SYNC);
            while(feedout(2*1024*1024*sizeof(char))){;}

            framecontrol[0].STATED = 2;
            framecontrol[0].ATT = 3;
            framecontrol[0].LAYER = i;
            framecontrol[0].NUMD = 2*1024*1024*sizeof(char);
            framecontrol[0].PIECEEND = 0;
            framecontrol[0].WP = 0;

            (framecontrol[0].start)[18] = framecontrol[0].ATT;
            (framecontrol[0].start)[19] = framecontrol[0].LAYER;
            (framecontrol[0].start)[20] = framecontrol[0].NUMD;
            (framecontrol[0].start)[21] = framecontrol[0].PIECEEND;
            (framecontrol[0].start)[22] = framecontrol[0].WP;

            (framecontrol[0].start)[17] = framecontrol[0].STATED;

            msync((framecontrol[0].start), 24*sizeof(int), MS_SYNC);

            k=0;
            qDebug() << "...";
        }
    }
    if(k >= 0)
    {
        //msync(readtemp[1].fbV, 2*1024*1024*sizeof(char), MS_SYNC);
        while(feedout(k*sizeof(char))){;}
        //while(feedout(4*k*sizeof(char))){;}

        if(i==9){
            framecontrol[0].STATED = 3;
        }
        else{
            framecontrol[0].STATED = 2;
        }

        framecontrol[0].ATT = 3;
        framecontrol[0].LAYER = i;
        framecontrol[0].NUMD = k*sizeof(char);
        //framecontrol[0].NUMD = 4*k*sizeof(char);
        framecontrol[0].PIECEEND = 1;
        framecontrol[0].WP = 0;

        (framecontrol[0].start)[18] = framecontrol[0].ATT;
        (framecontrol[0].start)[19] = framecontrol[0].LAYER;
        (framecontrol[0].start)[20] = framecontrol[0].NUMD;
        (framecontrol[0].start)[21] = framecontrol[0].PIECEEND;
        (framecontrol[0].start)[22] = framecontrol[0].WP;

        (framecontrol[0].start)[17] = framecontrol[0].STATED;

        msync((framecontrol[0].start), 24*sizeof(int), MS_SYNC);

        qDebug() << "...!";

    }
    file_name.close();
    //printf("conv%d_h_biases_0.txt has been sent!\n",i);

    //QString s;
    //s.sprintf("conv%d_h_biases_0.txt has been sent!\n",i);
    //qDebug()<<s;
    //ui->label_3->setText(s);
    //ui->label_3->show();
    return(0);
}




Thread::Thread()
{

}

void Thread::run()
{
    emit send(QString("Read_table"));
    readtable();
    emit send(QString("transfer table complete..."));

    emit send(QString("Read_Weight"));

    for (int i = 1; i <= 9; i++)
    {
        readwdata_2m(i);
        QString s;
        s.sprintf("conv_%d_h_weights_0.txt has been sent!\n",i);
        emit send(s);
    }

    for (int i = 1; i <= 9; i++)
    {
        readbdata_2m(i);
        QString s;
        s.sprintf("conv%d_h_biases_0.txt has been sent!\n",i);
        emit send(s);
    }


    emit send(QString("Read_done"));
    emit send(QString("The CASSANN-X is working"));

}
